import java.io.*;
import java.net.*;
import java.rmi.UnexpectedException;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;


public class ItemHandler {
	static private Namespace ns = Namespace.getNamespace("http://www.cs.au.dk/dWebTek/2011");
	static private String shopUrl = "http://services.brics.dk/java/cloud";
	static private String shopKey = "8259472FBED5DE4AD1FB0839";

	/**
	 * Create an item with a given name
	 * @param itemName the name of the item
	 */
	public void createItem(String itemName) throws UnexpectedException{
		String request = "/createItem";

		//define xml tree
		Document xmlDoc = new Document();

		//add root element
		Element root = new Element("createItem");
		root.setNamespace(ns);
		xmlDoc.setRootElement(root);

		//add child element "customerName"
		Element ele = new Element("shopKey", ns);
		ele.setText(shopKey);
		root.addContent(ele);

		//add child element "customerPass"
		ele = new Element("itemName", ns);
		ele.setText(itemName);
		root.addContent(ele);

		//send data to cloud
		sendToCloud(request, xmlDoc); 
	}

	/**
	 * Modifies an item
	 * 
	 * @param itemID the id of the item to be modified
	 * @param newItemName the new name
	 * @param newItemPrice the new price
	 * @param newItemDescription the new description
	 * @param newItemPictureURL URL to the picture representing the item
	 * 
	 * @throws UnexpectedException 
	 */
	public void modifyItem(String itemID, String newItemName, String newItemPrice, String newItemPictureURL, String newItemDescription) throws UnexpectedException{
		String request = "/modifyItem";

		//create XML document
		Document xmlDoc = new Document();

		//add root element
		Element root = new Element("modifyItem");
		root.setNamespace(ns);
		xmlDoc.setRootElement(root);

		//add child element "shopKey"
		Element ele = new Element("shopKey", ns);
		ele.setText(shopKey);
		root.addContent(ele);

		//add child element "itemID"
		ele = new Element("itemID", ns);
		ele.setText(itemID);
		root.addContent(ele);

		//add child element "itemName"
		ele = new Element("itemName", ns);
		ele.setText(newItemName);
		root.addContent(ele);

		//add child element "itemPrice"
		ele = new Element("itemPrice", ns);
		ele.setText(newItemPrice);
		root.addContent(ele);

		//add child element "itemURL"
		ele = new Element("itemURL", ns);
		ele.setText(newItemPictureURL);
		root.addContent(ele);

		//add child element "itemDescription"
		ele = new Element("itemDescription", ns);
		ele.setText(newItemDescription);
		root.addContent(ele);

		//send data to cloud
		sendToCloud(request, xmlDoc);
	}

	/**
	 * Adjust the stock of an item
	 * 
	 * @param itemID the id of the item to be modified
	 * @param stockAdjustment how many items to add, can be negative
	 * @throws UnexpectedException
	 */
	public void adjustItemStock(String itemID, String stockAdjustment) throws UnexpectedException{
		String request = "/adjustItemStock";

		//define xml tree
		Document xmlDoc = new Document();

		//add root element
		Element root = new Element("adjustItemStock");
		root.setNamespace(ns);
		xmlDoc.setRootElement(root);

		//add child element "shopKey"
		Element ele = new Element("shopKey", ns);
		ele.setText(shopKey);
		root.addContent(ele);

		//add child element "itemID"
		ele = new Element("itemID", ns);
		ele.setText(itemID);
		root.addContent(ele);

		//add child element "adjustment"
		ele = new Element("adjustment", ns);
		ele.setText(stockAdjustment);
		root.addContent(ele);

		//send data to cloud
		sendToCloud(request, xmlDoc); 
	}
	
	/**
	 * Sell an amount of one item to one customer
	 * @param itemID Id of the item
	 * @param customerID Id of the customer
	 * @param saleAmount amount of the items sold
	 * @return Document the resulting saleResponse, or null if it doesnt exist
	 */
	static public Document sellItem(String itemID, String customerID, String saleAmount){
		String request = "/sellItems";

		//define xml tree
		Document xmlDoc = new Document();

		//add root element
		Element root = new Element("sellItems");
		root.setNamespace(ns);
		xmlDoc.setRootElement(root);

		//add child element "shopKey"
		Element ele = new Element("shopKey", ns);
		ele.setText(shopKey);
		root.addContent(ele);

		//add child element "itemID"
		ele = new Element("itemID", ns);
		ele.setText(itemID);
		root.addContent(ele);

		//add child element "adjustment"
		ele = new Element("customerID", ns);
		ele.setText(customerID);
		root.addContent(ele);
		
		//add child element "adjustment"
		ele = new Element("saleAmount", ns);
		ele.setText(saleAmount);
		root.addContent(ele);

		//send data to cloud
		try {
			return sendToCloud(request, xmlDoc);
		} catch (UnexpectedException e) {
			e.printStackTrace();
		} 
		
		return null;
	}

	/**
	 * connect to the cloud
	 * 
	 * @param request e.g. /login or /adjustItemStock
	 * @param xmlDoc the xml document, or null if nothing is to be sent
	 * @return the document returned from the cloud, or null if nothing is returned
	 * @throws UnexpectedException
	 */
	public static Document sendToCloud(String request, Document xmlDoc) throws UnexpectedException{
		try {
			HttpURLConnection c = (HttpURLConnection) new URL(shopUrl + request).openConnection();

			//outputter with prettyprint added
			XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());

			//send request to server
			if( xmlDoc != null){
				c.setDoOutput(true);
				OutputStreamWriter writer = new OutputStreamWriter(c.getOutputStream(), "UTF-8");
				outputter.output(xmlDoc, writer);
				writer.close();
			}

			//recieve response from server
			InputStream inputStream = c.getInputStream();
			if( inputStream.available() != 0){
				Document response = new SAXBuilder().build(inputStream);
//				outputter.output(response, System.out);
				return response;
			}

			return null;

		} catch (IOException e) {
			e.printStackTrace();
		} catch (JDOMException e) {
			e.printStackTrace();
		}
		throw new UnexpectedException("Something went wrong communicating with the cloud");
	}


	public ItemHandler(){

//		try {
//			createItem("The Matrix 3");
//			modifyItem("977", "The Matrix", "1335", "http://www.dr.dk/php/bu/troldopedia/admin/images_univers/matrix.jpg", "Some other movie");
//			adjustItemStock("977", "1");
//		} catch (UnexpectedException e) {
//			e.printStackTrace();
//		}
	}

	public static void main(String args[]) throws IOException {
		new ItemHandler();
	}
}